<template>
  <el-col>
    <el-row :gutter="15">
      <el-col :span="8">
        <el-cascader class="input-block"
          v-model="casSelects"
          :props="casProps"
          :options="casOptions"
          @active-item-change="handleCasItemChange"
          @change="handleCasChange"/>
      </el-col>
      <el-col :span="12">
        <el-select class="input-block"
          ref="selectEl"
          multiple
          clearable
          placeholder="请选择"
          v-model="selectedResult"
          @change="handleSelectChange">
          <el-option
            v-for="item in selectsData"
            :key="item.value"
            :label="item.name"
            :value="item">
          </el-option>
        </el-select>
      </el-col>
    </el-row>
  </el-col>
</template>
<script>
  /**
   * 级联 + 末级多选
   */
  import serviceApi from 'api/service'
  export default {
    props: {
      value: {
        type: Array
      },
      data: {
        type: Object
      }
    },
    mounted () {
      // 只需要是否为编辑状态  如需要其他 则引入vuex
      this.$isEditor = this.$store.state.service.service_release_type.isEditor
      this._beforeInit()
    },
    data () {
      return {
        selectsData: [], // 下拉多选数据
        selectedResult: [],
        casSelects: [],
        casOptions: [],
        casProps: {
          label: 'name'
        },
        valueToTextObj: {}
      }
    },
    methods: {
      _beforeInit () {
        /**
         * 防止value没更新，导致赋值渲染不能成功
         */
        this.$firstEditLoad = !0
        if (this.$isEditor && !this.value.length) {
          setTimeout(() => {
            this._beforeInit()
          }, 200)
          return !1
        }
        this._initData()
      },
      _initData () {
        console.log('12121')
        let curCasData = this.data
        this._getItemData({
          curCasData
        }, (data, isHasChild) => {
          this.casOptions = data
          if (this.$isEditor && this.$firstEditLoad) {
            let value = [curCasData.editorValues[0] - 0]
            this.casSelects = value
            if (isHasChild) {
              this.handleCasItemChange(value)
            } else {
              this.handleCasChange(value)
            }
          }
        })
      },
      handleCasItemChange (newCasVal) {
        let curCasData = this.data.children
        if (newCasVal.length > 1) {
          curCasData = this.$curCasData
        }
        this._getItemData({
          newCasVal: newCasVal,
          curCasData
        }, (data, isHasChild) => {
          // this.$curCasData = curCasData
          let casOptions = this.casOptions
          if (newCasVal.length === 1) {
            let itemIndex = casOptions.findIndex(item => item.value === newCasVal[0])
            let cascaderItem = Object.assign(casOptions[itemIndex], {
              children: data.length ? data : undefined
            })
            this.$set(this.casOptions, itemIndex, cascaderItem)
          } else {
            newCasVal.forEach((item, index) => {
              let itemIndex = casOptions.findIndex(k => k.value === item)
              if (index === 0) {
                casOptions = casOptions[itemIndex].children
              } else if (index < newCasVal.length - 1) {
                casOptions = casOptions[itemIndex].children
              } else {
                casOptions[itemIndex].children = data.length ? data : undefined
              }
            })
          }
          // 编辑数据渲染
          if (this.$isEditor && this.$firstEditLoad) {
            let value = [...newCasVal, curCasData.editorValues[0] - 0]
            this.casSelects = value
            if (isHasChild) {
              this.handleCasItemChange(value)
            } else {
              this.handleCasChange(value)
            }
          }
        })
      },
      handleCasChange (newCasVal) {
        this._getItemData({
          newCasVal,
          isHasChild: false,
          curCasData: this.$curCasData
        }, (data) => {
          // console.log(data, this.$curCasData)
          this.selectsData = data
          let newSelectVal = []
          if (this.$isEditor && this.$firstEditLoad) {
            this.$firstEditLoad = !1 // 编辑初始化
            let editorVals = this.$curCasData.editorValues
            editorVals.forEach(item => {
              let tempItem = data.find(k => k.value + '' === item + '')
              tempItem && newSelectVal.push(tempItem)
            })
          }
          this.selectedResult = newSelectVal
        })
      },
      handleSelectChange (selectedVal = []) {
        let values = []
        let valueTexts = []
        if (selectedVal.length) {
          // 初始化 级联单选的数据
          this.casSelects.forEach(cItem => {
            values.push(cItem)
            valueTexts.push(this.valueToTextObj[cItem])
          })
          // 加载末级多选数据
          let tempTextArr = []
          let tempValueArr = []
          selectedVal.forEach(sItem => {
            tempValueArr.push(sItem.value + '') // 强行转为字符串
            tempTextArr.push(sItem.name)
          })
          values.push(tempValueArr)
          valueTexts.push(tempTextArr)
        }
        this.$emit('change', values, valueTexts)
      },
      _getItemData ({newCasVal = [], isHasChild = true, curCasData}, callback) {
        // 暂时只做URL模式
        let { url, text, value, parentValueType = 0 } = JSON.parse(curCasData.attrValue)
        if (newCasVal.length) {
          let casId
          // jsonData 中有一个字段parentValueType
          // 值为1表示所有子集都根据顶级value取获取数据  其他取父级
          // 两级的没有parentValueType字段
          if (parentValueType - 0 === 1) {
            casId = newCasVal[0] // 首级
          } else {
            casId = newCasVal[newCasVal.length - 1] // 末级
          }
          url += casId
        }
        /**
         * 判断是否为末级
         * 末级多选的需要判断后两级是否为末级
         * 有末级 则需要children属性做级联
         * 无末级 则加载多选下拉
         * 级联没有下级  选择则触发change事件  再根据curCasData数据获取多选下拉数据
         */
        if (isHasChild) {
          isHasChild = curCasData.children ? !!curCasData.children.children : false
          // 判断完 赋值下一级
          this.$curCasData = curCasData.children
        }
        // {url, text, value} URL模式下 约定的格式
        serviceApi.dict(url).then(({data}) => {
          // 请求完成 启用编辑模式
          data = this._formatData(data, {
            text,
            value,
            isHasChild
          })
          callback && callback(data, isHasChild)
        })
      },
      _formatData (data = [], {text, value, isHasChild = false}) {
        data = data.map(item => {
          item.name = item[text]
          item.value = item[value]
          item.valueObj = { name: item[text], value: item[value] }
          this.valueToTextObj[item.value] = item.name // 子集 暂定由value定 valueText 默认value相同 则valueText相同
          return {
            ...item,
            children: isHasChild ? [] : undefined // 末级则无
          }
        })
        return data
      }
    }
  }
</script>
